﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;

namespace Shared.SwaggerHelper
{
    /// <summary>
    /// Swagger 扩展
    /// </summary>
    public static class SwaggerExtensions
    {
        /// <summary>
        /// 默认版本号
        /// </summary>
        static readonly string Default_GroupName = "v1";
        /// <summary>
        /// [自定义扩展]注册 Swagger 服务
        /// 支持多版本WebApi
        /// </summary>
        /// <param name="services"></param>
        /// <param name="applicationName">
        /// 可以通过 
        /// Assembly.GetExecutingAssembly().GetName().Name 
        /// 获取应用程序名
        /// </param>
        /// <param name="provider"></param>
        /// <returns></returns>
        public static IServiceCollection AddSwaggerGenExt(this IServiceCollection services, string applicationName, IApiVersionDescriptionProvider provider = null)
        {
            services.AddSwaggerGen(option =>
            {
                if (null == provider)
                {
                    option.SwaggerDoc(Default_GroupName, new OpenApiInfo
                    {
                        Title = $"WebApi {Default_GroupName}",
                        Version = Default_GroupName,
                        Description = applicationName + " WebApi",
                        Contact = new OpenApiContact()
                        {
                            Name = "QuickFramework.Core Team",
                            Email = "",
                            Url = new Uri("http://localhost")
                        }
                    });
                }
                else
                {
                    var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
                    option.OperationFilter<SwaggerOperationFilter>();
                    foreach (var item in provider.ApiVersionDescriptions)
                    {
                        option.SwaggerDoc(item.GroupName, new OpenApiInfo
                        {
                            Title = $"WebApi {item.GroupName}",
                            Version = item.ApiVersion.ToString(),
                            Description = applicationName + " WebApi",
                            Contact = new OpenApiContact()
                            {
                                Name = "QuickFramework.Core Team",
                                Email = "",
                                Url = new Uri("http://localhost")
                            }
                        });
                    }
                }
                #region 读取XML信息
                //使用反射获取XML文件名称,并构建出文件的路径
                var xmlFile = $"{applicationName}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                //启用XML注释,该方法第二个参数启用控制器的注释,默认为false
                option.IncludeXmlComments(xmlPath, true);
                #endregion

                #region 启用swagger 的 JWT 验证功能
                option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输),请输入: <span style='color:red'>Bearer</span> <span style='color:blue'>{token}</span>（注意两者之间是一个空格）\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                option.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference 
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[] { }
                    }
                });
                #endregion
            });
            return services;
        }
        /// <summary>
        /// [自定义扩展] 使用Swagger中间件
        /// 支持多版本WebApi
        /// </summary>
        /// <param name="app"></param>
        /// <param name="provider"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseSwaggerUIExt(this IApplicationBuilder app, IApiVersionDescriptionProvider provider=null)
        {
            app.UseSwagger();
            app.UseSwaggerUI(option =>
            {
                if (provider == null)
                {
                    option.SwaggerEndpoint($"/swagger/{Default_GroupName}/swagger.json", $"WebApi {Default_GroupName}");
                }
                else
                {
                    foreach (var desciption in provider.ApiVersionDescriptions)
                    {
                        option.SwaggerEndpoint($"/swagger/{desciption.GroupName}/swagger.json", desciption.GroupName);
                    }
                }
            });
            return app;
        }
    }
}
